"""
权限验证依赖模块
"""
from fastapi import Header, HTTPException, Depends
from typing import List

from models.m import User, Role, Permission, UserRoleRelation, RolePermissionRelation, UserStatus
from tool.jwt_utils import verify_token


async def get_current_user(authorization: str | None = Header(None)) -> User:
    """
    获取当前登录用户（依赖函数）
    用于需要登录才能访问的接口
    
    Args:
        authorization: Bearer Token，从请求头获取
        
    Returns:
        User: 当前登录用户对象
        
    Raises:
        HTTPException: 401 未授权或 Token 无效
        HTTPException: 403 用户被禁用
    """
    if not authorization or not authorization.lower().startswith("bearer "):
        raise HTTPException(status_code=401, detail="未授权：缺少Bearer Token")
    
    token = authorization.split(" ", 1)[1].strip()
    payload = verify_token(token)
    if not payload or not payload.get("user_id"):
        raise HTTPException(status_code=401, detail="无效或过期的Token")
    
    user_id = payload["user_id"]
    user = await User.get_or_none(id=user_id)
    if not user:
        raise HTTPException(status_code=401, detail="用户不存在")
    
    if user.status != UserStatus.ACTIVE:
        raise HTTPException(status_code=403, detail="用户已被禁用")
    
    return user


async def get_user_roles(user: User) -> List[str]:
    """
    获取用户的所有角色代码列表
    
    Args:
        user: 用户对象
        
    Returns:
        List[str]: 角色代码列表，如 ['admin', 'author']
    """
    user_roles = await UserRoleRelation.filter(user=user).prefetch_related('role')
    role_codes = [ur.role.code for ur in user_roles if ur.role.is_active]
    return role_codes


async def get_user_permissions(user: User) -> List[str]:
    """
    获取用户的所有权限代码列表（通过角色关联）
    
    Args:
        user: 用户对象
        
    Returns:
        List[str]: 权限代码列表，如 ['novel:create', 'chapter:publish']
    """
    # 获取用户的所有角色
    user_roles = await UserRoleRelation.filter(user=user).prefetch_related('role')
    role_ids = [ur.role.id for ur in user_roles if ur.role.is_active]
    
    if not role_ids:
        return []
    
    # 获取这些角色的所有权限
    role_permissions = await RolePermissionRelation.filter(
        role_id__in=role_ids
    ).prefetch_related('permission')
    
    permission_codes = [rp.permission.code for rp in role_permissions if rp.permission.is_active]
    # 去重
    return list(set(permission_codes))


def require_role(*required_roles: str):
    """
    角色权限依赖函数（推荐使用）
    在路由中使用：user: User = Depends(require_role("admin", "author"))
    
    Args:
        *required_roles: 要求的角色代码，用户只需拥有其中一个即可
        
    Returns:
        依赖函数，用于 FastAPI 的 Depends
        
    Raises:
        HTTPException: 403 权限不足
    """
    async def role_checker(user: User = Depends(get_current_user)):
        user_roles = await get_user_roles(user)
        if not any(role in user_roles for role in required_roles):
            raise HTTPException(
                status_code=403,
                detail=f"需要以下角色之一: {', '.join(required_roles)}"
            )
        return user
    return role_checker


def require_permission(*required_permissions: str):
    """
    权限检查依赖函数（推荐使用）
    在路由中使用：user: User = Depends(require_permission("novel:create"))
    
    Args:
        *required_permissions: 要求的权限代码，用户必须拥有所有权限
        
    Returns:
        依赖函数，用于 FastAPI 的 Depends
        
    Raises:
        HTTPException: 403 权限不足
    """
    async def permission_checker(user: User = Depends(get_current_user)):
        user_permissions = await get_user_permissions(user)
        missing = [perm for perm in required_permissions if perm not in user_permissions]
        if missing:
            raise HTTPException(
                status_code=403,
                detail=f"缺少以下权限: {', '.join(missing)}"
            )
        return user
    return permission_checker

